#include "../gba_hack.h"
#include "../fe8.h"

static void setmap_tile(u16*map,int x,int y,u16 tile){
    map += y*0x20;
    map[x] = tile;
}

static u16 getmap_tile(u16*map,int x,int y){
    map+= y*0x20;
    return map[x];
}


static void test(u32 r0){
    CALLT(0x8000B4C);
}

// static void init(u32 r0){

// }

const uint32_t rom8A728E4[] = {
    #if 0
    //有按键时，触发一次test
    2,test,
    0xa000b,0,
    #elif 0
    //一次触发test
    3,test,
    0xa000b,0,
    #else

    #endif
    0,0, //结束
};

/*
有关0x85C5664 数据定义

*/
struct _85C5664{
    #define show_set_pos(x,y,width) \
        (x)|((y)<<8)|(width<<0x10)
            /*  位置 &0xff 偏移X*8,  (>>8) &0xff  偏移Y*8
                (>>16)&0xf  物品栏的宽度
            */
    u32     u0_;        //0xE0101   ,
    u32     u4_;        //0
    u32     u8_;        //指向 85C4D1C
    u32     uC_;        //A键, 触发        0
    u32     u10_;       //B键，返回时触发   0
    u32     u14_;      //0,0,0
    u32     u18_;       //B键取消时，触发    8022828+1
    u32     u1C_;       //R键触发           8050294+1
    u32     u20_;       //R键触发，         8024538+1
    #define show_key_callback(event,A,B,R,R2,ret) \
    0,(u32)(event),(u32)(A),(u32)(B),0,(u32)(ret),(u32)(R),(u32)(R2)
};

/*
_85C4D1C 数据为6-1个，
最后一个为{0，0，0，0}

*/
struct _85C4D1C{
    u32     u0_;        //应该是名字
    u32     u4_;
    u32     u8_;        //0x4300
    u32     uC_;        //0x802339D
    u32     u10_;       //处理显示物品,返回0则显示
    u32     u14_;       //点击确定时处理
    u32     u18_;       //0
    u32     u1C_;       //当被选中时，触发
    u32     u20_;       //nullsub,离开时触发?
#define item_def_event(name,id,click,select)   \
    (u32)(name),0,(u32)(id), \
    0x802339D,0x8023319,(u32)(click),0, \
    (u32)(select),0x0802346C+1,

#define ok_def_event(name,value1,value2,click) \
    (u32)(name),value1,value2,0x80501BD,0,      \
    (u32)(click),                                \
    0,0,0,
};

typedef struct _85C5664 item_show_t;
typedef struct _85C4D1C item_event_t;
typedef struct _85C5664 menu_show_t;
typedef struct _85C4D1C menu_event_t;

/*
85E06B0
    为游戏事件

*/

//在点击确定"物品"中测试
static u32 hackItem(u32 a1,u32 a2){
    // uint32_t v5 = //CALLT(0x8002C30,0x8A7291C,r2);
    //     CALLT(0x8002C30,rom8A728E4,r2);
    //CALLT(0x80232B0,0,r2);
    //CALLT(0x804F970,0x85C5664,r2);
    #if 0
    return CALLT(0x80232B0,a1,a2);  //返回0，则不显示
    //返回23，则关闭游标
    #endif

    if(getb(a2+0x3d)==1){
        CALLT(0x80034D0);   //清除2026A90，0x2026E10 的内存数据
        CALLT(0x8003508,4);  //处理道具调色板
        CALLT(0x8003C50);   //设置2028E74[0] 为0xff

        //会处理图层0的背景 (显示道具图标和数量)
        int v3 = CALLT(0x804F970,0x85C5664); //返回创建的事件

        CALLT(0x8005544,
            0,              //显示头像的模式,1为动态显示，会眨眼(当关闭菜单时，不会清除头像)，0为静态显示
            CALLT(0x8018FCC,get(0x3004DF0)) //返回角色大头像ID
            ,0xb0,      //头像坐标X
            12,         //头像坐标Y
            2           //显示头像类型 ,      2:朝向左边，3,朝向右边,4左边，被裁剪底部8个像素，5，右边，裁剪底部8个像素...
        );

        CALLT(0x800635C,0,
        5       //5 为静态显示头像,1为眨眼(频率高)，2,为眨眼
        );

        //处理图层1的背景   (物品栏的背景，和物品栏帮助)
        CALLT(0x801E2E0,v3,get(0x3004DF0),
        0xf,        //道具帮助栏X偏移
        0xb       //道具帮助栏Y偏移
        );
        return 23;
    }
    else{
        return 0;
    }
}

static const item_event_t   item_fuse_event[];
static const item_show_t    item_key_proc;
static u32 item_fuse_ret(u32 event,u32 event2);
static u32 item_fuse_A();
static u32 item_fuse_R();
static u32 item_fuse_click();
static u32 item_fuse_select();
static u32 item_fuse_ok();
static u32 item_fuse_cancel();
static const menu_event_t item_fuse_ok_event[];
#define get_item_index(event)           getb(event+0x61)
#define set_item_select(event,value)    strb(event+0x68+3,value)
#define get_item_select(event)    getb(event+0x68+3)
#define get_unit()              get(0x3004DF0)

static const item_show_t    item_key_proc = {
    show_set_pos(1,1,0xe),
    show_key_callback(
        //0x85C4D1C,
        item_fuse_event,
    //0,
    item_fuse_A,
    0,item_fuse_R,0,
    item_fuse_ret
    //0x8022828+1
    ),
};

static const item_event_t item_fuse_event[] = {
{item_def_event("",0x4300,item_fuse_click,item_fuse_select)},
{item_def_event("",0x4400,item_fuse_click,item_fuse_select)},
{item_def_event("",0x4500,item_fuse_click,item_fuse_select)},
{item_def_event("",0x4600,item_fuse_click,item_fuse_select)},
{item_def_event("",0x4700,item_fuse_click,item_fuse_select)},
{0,0,0},
};

static const menu_show_t item_fuse_menu = {
    show_set_pos(0,0,0x5),
    show_key_callback(item_fuse_ok_event,0,0,0,0,0),
};

static const menu_event_t item_fuse_ok_event[] = {
    {ok_def_event(0x80DCAA0,0x7bb,0x3200,
    //0x80238A4+1
    item_fuse_ok
    )},
    {ok_def_event(0x80DCA98,0x7bc,0x3300,
    //0x80234C0+1
    item_fuse_cancel
    )},
    {0},
};

static void draw_bg();

static u32 item_fuse_proc(u32 value){
    u16 *item_ptr = get_unit() + 0x1e;
    u32 item = 0;
    u16 items[5];
    u16 *item_tmp_ptr = items;
    items[0] = 0;
    items[1] = 0;
    items[2] = 0;
    items[3] = 0;
    items[4] = 0;
    int i;
    for(i=0;i<5;i++){
        if(value&(1<<i)){
            // CALLT(0x801915C,get_unit(),getb(0x203A966));
            // strb(0x203A966,i);
            if(item<0x100){
                items[i] = 0;
                item <<= 8;
                item |= (item_ptr[i]&0xff);
            }
        }
        else{
            item_tmp_ptr[0] = item_ptr[i];
            item_tmp_ptr++;
        }
    }
    *((int*)0x203fe60) = value;

    i = 0;
    item_ptr[0] = items[0];
    item_ptr[1] = items[1];
    item_ptr[2] = items[2];
    item_ptr[3] = items[3];
    item_ptr[4] = items[4];

    //item_ptr[2] = 0;

    //CALLT(0x80238A4);   //执行丢弃函数

    if(item==0x0101){
        //两铁剑测试
    }
    else if(item==0x317){
        //钢剑+银枪
    }
}

//道具融合，确定
static u32 item_fuse_ok(u32 a1,u32 a2){
    ((int*)0x203fe44)[7+2] = a1; //内存位置
    ((int*)0x203fe44)[8+2] = a2; //内存位置
    u32 event = get(a1+0x14);
    u32 value = get_item_select(event);
    item_fuse_proc(value);
    CALLT(0x8022700);       //单位已经移动

    //CALLT(0x8028E0C,get_unit(), *(_WORD *)(get_unit() + 0x1E + 2 * 0))

    CALLT(0x804F610);       //清理图层
    CALLT(0x8003C68,0);     //清理?
    CALLT(0x804FCAC,CALLT(0x8003C50));  //关闭菜单，显示地图和角色

    #if 1
    //使用游戏内指针测试
    CALLT(0x800D340,
    //0x8a61210
    0x8a6129c
    ,1);
    #endif

    #if 0
    //测试用的，合成为突刺剑
    CALLT(0x8011640,
    //get(0x203ffd0),
    0,
    get_unit(),0x9); //突刺剑
    #endif

    //str(a1+0xc,0);
    //return get(0x203ffd0);
    return 0x21;
}

//道具融合，取消
static u32 item_fuse_cancel(u32 a1,u32 a2){
    // ((int*)0x203fe44)[7] = a1; //内存位置
    u32 event = get(a1+0x14);
    set_item_select(event,0);
    // ((int*)0x203fe44)[8] = a2; //内存位置

    //清理武器文字
    u16 *map =0x2022ca8 + 0x800*0;
    int x,y,i;
    for(i=0;i<5;i++){
        for(y=2+i*2;y<4+i*2;y++){
            for(x=2;x<2+8;x++){
                u16 tile = 0;
                setmap_tile(map,x-1,y-2+14,tile);
            }
        }
    }
    gba_memcpy(0x06006000, 0x2022ca8 + 0x800*0,0x800);

    return 11;
}

static u32 item_fuse_click(u32 a1,u32 a2){
    //使用菜单
    //return CALLT(0x80233ec,a1,a2); //默认菜单
    ((int*)0x203fe44)[0] = a1; //内存位置
    int idx = get_item_index(a1);
    u32 value = get_item_select(a1);
    int num = 0;
    if(value){
        num = 1;
    }

    if(value&(1<<idx)){
        //已经被选中了，取消选中
        value &= ~(1<<idx);
        num = 0;
    }
    else{
        value |= 1<<idx;
        num ++;
    }

    //绘制背景
    draw_bg();

    //
    int i;
    int yoffset = 0;
    int x,y;
    u16 *map =0x2022ca8 + 0x800*0;
    for(i=0;i<5;i++){
        for(y=2+i*2;y<4+i*2;y++){
            for(x=2;x<2+8;x++){
                u16 tile = 0;
                setmap_tile(map,x-1,y-2+14,tile);
            }
        }
    }

    if(value){
        for(i=0;i<5;i++){
            //复制目标武器的图层到现在图层
            if(value&(1<<i)){
                for(y=2+i*2;y<4+i*2;y++){
                    for(x=2;x<2+8;x++){
                        u16 tile = getmap_tile(map,x,y);
                        setmap_tile(map,x-1,yoffset+14,tile);
                    }
                    yoffset ++;
                }
            }
        }
    }

    gba_memcpy(0x06006000, 0x2022ca8 + 0x800*0,0x800);
    gba_memcpy(0x06006800, 0x2022ca8 + 0x800*1,0x800);

    if(num>1){
        //两件物品，合成
        #if 0
        u16 *item_ptr = get_unit() + 0x1e;
        u32 item = 0;

        for(i=0;i<5;i++){
            if(value&(1<<i)){
                item <<= 8;
                item |= (item_ptr[i]&0xff);
                if(item>=0x100){
                    //达到两件物品
                    break;
                }
            }
        }

        if(item==0x0101){
            //两铁剑测试
        }
        else if(item==0x317){
            //钢剑+银枪
        }
        #endif
        #if 0
        //显示是否丢弃
        u32 ptr = CALLT(0x804FA24,
        0x85C55D4,      //丢弃操作
        0x50a0f,
        a1
        );
        #endif
        set_item_select(a1,value);
        u32 ptr = CALLT(0x804FA24,
        //0x85C55D4,      //丢弃操作
        (u32)&item_fuse_menu,
        0x50a0f,
        a1
        );

        //((int*)0x203fe44)[3] = item; //内存位置
        //return 0x84;
    }


    //判断是否达到两件物品

    set_item_select(a1,value);

    ((int*)0x203fe44)[1] = idx;
    return 0;
}

static u32 item_fuse_select(u32 a1,u32 a2){
    return CALLT(0x802345C,getb(a2+0x3c));
}

static u32 item_fuse_R(u32 event){
    draw_bg();
    gba_memcpy(0x06006800, 0x2022ca8 + 0x800*1,0x800);
    return 0;
}

static u32 item_fuse_A(){
    //进入时触发
    return 0;
}

static void draw_bg(){
    #if 1
    u16 *ptr = 0x2022ca8 + 0x800*1;
    int y = 0;
    int x = 0;
    for(y=0;y<8;y++){
        for(x=0;x<14;x++){
            u16 tile = getmap_tile(ptr,x+15,y+11);
            setmap_tile(ptr,x,y+13,tile);
        }
    }
    #endif
}

static u32 item_fuse_ret(u32 event,u32 event2){
    //return 0;                   //不返回上一个界面
    return CALLT(0x8022828);    //默认返回
}

static u32 hackItem2(u32 a1,u32 a2){
    //新的测试程序
    if(getb(a2+0x3d)!=1){
        return 0;
    }

    //开始

    CALLT(0x80034D0);   //清除2026A90，0x2026E10 的内存数据
    CALLT(0x8003508,4);  //处理道具调色板
    CALLT(0x8003C50);   //设置2028E74[0] 为0xff

    //会处理图层0的背景 (显示道具图标和数量)
    int v3 = //CALLT(0x804F970,0x85C5664); //返回创建的事件
        CALLT(0x804F970,&item_key_proc);

    #if 0
    //不需要显示头像
    CALLT(0x8005544,
        0,              //显示头像的模式,1为动态显示，会眨眼(当关闭菜单时，不会清除头像)，0为静态显示
        CALLT(0x8018FCC,get(0x3004DF0)) //返回角色大头像ID
        ,0xb0,      //头像坐标X
        12,         //头像坐标Y
        2           //显示头像类型 ,      2:朝向左边，3,朝向右边,4左边，被裁剪底部8个像素，5，右边，裁剪底部8个像素...
    );
    CALLT(0x800635C,0,
    5       //5 为静态显示头像,1为眨眼(频率高)，2,为眨眼
    );
    #endif

    //处理图层1的背景   (物品栏的背景，和物品栏帮助)
    CALLT(0x801E2E0,v3,get(0x3004DF0),
    0xf,        //道具帮助栏X偏移
    0xb         //道具帮助栏Y偏移
    );
    //draw_bg();
    //gba_memcpy(0x06006800, 0x2022ca8 + 0x800*1,0x800);


    return 23;
}

#if 0
HACK_DATA(0x85C52AC)
const u32 _85C52AC = hackItem2;

#if 0
HACK_DATA(0x80232EC)
const u32 _80232EC = 0xf7e32100
    +5;      //+5不眨眼，+1 眨眼
    //+1;       //+1 眨眼
#endif

#else
static int ret_1(){
    return 1;
}

//暂时使用运输队作为融合
HACK_DATA(0x85C52EC)
const u32 _85C52EC = ret_1;

HACK_DATA(0x85C52E0)
const u8    *_85C52E0 = "\x81\x80\x8e\xc2\x88\x98";     //"融合"

HACK_DATA(0x85C52F4)
const u32 _85C52F4 = hackItem2;
#endif

